From d80c130d7f988483d307aceb704f7780adc50d79 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Timm=20B=C3=A4der?= Date: Sat, 25 Apr 2020 17:50:11 +0200 Subject: [PATCH] GdkEvent: Save history in a GArray Instead of a less efficient GList. --- gdk/gdkevents.c | 38 +++++++++++++++++++++++++++++--------- gdk/gdkevents.h | 3 ++- gdk/gdkeventsprivate.h | 10 +++++----- gtk/gtkgesturestylus.c | 12 +++++++----- 4 files changed, 43 insertions(+), 20 deletions(-) diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c index 9d2a689381..f1cae55a4f 100644 --- a/gdk/gdkevents.c +++ b/gdk/gdkevents.c @@ -671,22 +671,24 @@ gdk_motion_event_push_history (GdkEvent *event, GdkEvent *history_event) { GdkMotionEvent *self = (GdkMotionEvent *) event; - GdkTimeCoord *hist; + GdkTimeCoord hist; GdkDevice *device; gint i, n_axes; g_assert (GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY)); g_assert (GDK_IS_EVENT_TYPE (history_event, GDK_MOTION_NOTIFY)); - hist = g_new0 (GdkTimeCoord, 1); - device = gdk_event_get_device (history_event); n_axes = gdk_device_get_n_axes (device); for (i = 0; i <= MIN (n_axes, GDK_MAX_TIMECOORD_AXES); i++) - gdk_event_get_axis (history_event, i, &hist->axes[i]); + gdk_event_get_axis (history_event, i, &hist.axes[i]); + + if (G_UNLIKELY (!self->history)) + self->history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord)); + + g_array_append_val (self->history, hist); - self->history = g_list_prepend (self->history, hist); } void @@ -2727,7 +2729,8 @@ gdk_motion_event_finalize (GdkEvent *event) g_clear_object (&self->tool); g_clear_pointer (&self->axes, g_free); - g_list_free_full (self->history, g_free); + if (self->history) + g_array_free (self->history, TRUE); GDK_EVENT_SUPER (event)->finalize (event); } @@ -2819,6 +2822,7 @@ gdk_motion_event_new (GdkSurface *surface, /** * gdk_motion_event_get_history: * @event: (type GdkMotionEvent): a motion #GdkEvent + * @out_n_coords: (out): Return location for the length of the returned array * * Retrieves the history of the @event motion, as a list of time and * coordinates. @@ -2826,15 +2830,31 @@ gdk_motion_event_new (GdkSurface *surface, * Returns: (transfer container) (element-type GdkTimeCoord) (nullable): a list * of time and coordinates */ -GList * -gdk_motion_event_get_history (GdkEvent *event) +GdkTimeCoord * +gdk_motion_event_get_history (GdkEvent *event, + guint *out_n_coords) { GdkMotionEvent *self = (GdkMotionEvent *) event; g_return_val_if_fail (GDK_IS_EVENT (event), NULL); g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY), NULL); + g_return_val_if_fail (out_n_coords != NULL, NULL); + + if (self->history && + self->history->len > 0) + { + GdkTimeCoord *result; - return g_list_reverse (g_list_copy (self->history)); + *out_n_coords = self->history->len; + + result = g_malloc (sizeof (GdkTimeCoord) * self->history->len); + memcpy (result, self->history->data, sizeof (GdkTimeCoord) * self->history->len); + + return result; + } + + *out_n_coords = 0; + return NULL; } /* }}} */ diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h index cd4a46d4d2..e702717541 100644 --- a/gdk/gdkevents.h +++ b/gdk/gdkevents.h @@ -471,7 +471,8 @@ gboolean gdk_grab_broken_event_get_implicit (GdkEvent *event) GDK_AVAILABLE_IN_ALL GType gdk_motion_event_get_type (void) G_GNUC_CONST; GDK_AVAILABLE_IN_ALL -GList * gdk_motion_event_get_history (GdkEvent *event); +GdkTimeCoord * gdk_motion_event_get_history (GdkEvent *event, + guint *out_n_coords); GDK_AVAILABLE_IN_ALL GType gdk_delete_event_get_type (void) G_GNUC_CONST; diff --git a/gdk/gdkeventsprivate.h b/gdk/gdkeventsprivate.h index c45df7cc61..0a7b1300cd 100644 --- a/gdk/gdkeventsprivate.h +++ b/gdk/gdkeventsprivate.h @@ -127,7 +127,7 @@ struct _GdkMotionEvent double y; double *axes; GdkDeviceTool *tool; - GList *history; + GArray *history; /* */ }; /* @@ -343,7 +343,7 @@ struct _GdkConfigureEvent /* * GdkProximityEvent: - * @tool: the #GdkDeviceTool associated to the event + * @tool: the #GdkDeviceTool associated to the event * * A proximity event indicates that a tool of a graphic tablet, or similar * devices that report proximity, has moved in or out of contact with the @@ -456,7 +456,7 @@ GdkEvent * gdk_button_event_new (GdkEventType type, double x, double y, double *axes); - + GdkEvent * gdk_motion_event_new (GdkSurface *surface, GdkDevice *device, GdkDevice *source_device, @@ -477,7 +477,7 @@ GdkEvent * gdk_crossing_event_new (GdkEventType type, double y, GdkCrossingMode mode, GdkNotifyType notify); - + GdkEvent * gdk_proximity_event_new (GdkEventType type, GdkSurface *surface, GdkDevice *device, @@ -537,7 +537,7 @@ GdkEvent * gdk_touch_event_new (GdkEventType type, double y, double *axes, gboolean emulating); - + GdkEvent * gdk_touchpad_event_new_swipe (GdkSurface *surface, GdkDevice *device, GdkDevice *source_device, diff --git a/gtk/gtkgesturestylus.c b/gtk/gtkgesturestylus.c index 5944f0252e..974d83f0a9 100644 --- a/gtk/gtkgesturestylus.c +++ b/gtk/gtkgesturestylus.c @@ -283,7 +283,8 @@ gtk_gesture_stylus_get_backlog (GtkGestureStylus *gesture, { GdkEvent *event; GArray *backlog_array; - GList *history = NULL, *l; + GdkTimeCoord *history = NULL; + guint n_coords = 0, i; g_return_val_if_fail (GTK_IS_GESTURE_STYLUS (gesture), FALSE); g_return_val_if_fail (backlog != NULL && n_elems != NULL, FALSE); @@ -291,14 +292,15 @@ gtk_gesture_stylus_get_backlog (GtkGestureStylus *gesture, event = gesture_get_current_event (gesture); if (event && GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY)) - history = gdk_motion_event_get_history (event); + history = gdk_motion_event_get_history (event, &n_coords); + if (!history) return FALSE; backlog_array = g_array_new (FALSE, FALSE, sizeof (GdkTimeCoord)); - for (l = history; l; l = l->next) + for (i = 0; i < n_coords; i++) { - GdkTimeCoord *time_coord = l->data; + GdkTimeCoord *time_coord = &history[i]; graphene_point_t p; g_array_append_val (backlog_array, *time_coord); @@ -320,7 +322,7 @@ gtk_gesture_stylus_get_backlog (GtkGestureStylus *gesture, *n_elems = backlog_array->len; *backlog = (GdkTimeCoord *) g_array_free (backlog_array, FALSE); - g_list_free (history); + g_free (history); return TRUE; } -- 2.30.2